home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWMenu / Sources / FWPullDM.cpp < prev   
Encoding:
Text File  |  1996-08-16  |  22.7 KB  |  731 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWPullDM.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWPULLDM_H
  13. #include "FWPullDM.h"
  14. #endif
  15.  
  16. #ifndef FWMNUBAR_H
  17. #include "FWMnuBar.h"
  18. #endif
  19.  
  20. #ifndef FWRESTYP_H
  21. #include "FWResTyp.h"
  22. #endif
  23.  
  24. #ifndef FWACQUIR_H
  25. #include "FWAcquir.h"
  26. #endif
  27.  
  28. // ----- Foundation Includes -----
  29.  
  30. #ifndef FWSTREAM_H
  31. #include "FWStream.h"
  32. #endif
  33.  
  34. #ifndef FWSTRING_H
  35. #include "FWString.h"
  36. #endif
  37.  
  38. //========================================================================================
  39. // File scope definitions
  40. //========================================================================================
  41.  
  42. #ifdef FW_BUILD_MAC
  43. #pragma segment fwmenu
  44. #endif
  45.  
  46. //========================================================================================
  47. //    Template Instantiations
  48. //========================================================================================
  49.  
  50. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollectionIterator, FW_CPullDownMenu)
  51. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollection, FW_CPullDownMenu)
  52.  
  53. #ifdef FW_USE_TEMPLATE_PRAGMAS
  54.  
  55. #pragma template_access public
  56. #pragma template FW_TOrderedCollection<FW_CPullDownMenu>
  57. #pragma template FW_TOrderedCollectionIterator<FW_CPullDownMenu>
  58.  
  59. #endif
  60.  
  61. //========================================================================================
  62. //    class FW_CPullDownMenu
  63. //========================================================================================
  64.  
  65. FW_DEFINE_CLASS_M0(FW_CPullDownMenu)
  66.  
  67. // This class is archivable, but we provide the archiving implementation in a separate
  68. // translation unit in order to enable deadstripping of the archiving-related code
  69. // in parts that do not use archiving with this class.
  70.  
  71. //----------------------------------------------------------------------------------------
  72. //    FW_CPullDownMenu::FW_CPullDownMenu
  73. //----------------------------------------------------------------------------------------
  74.  
  75. FW_CPullDownMenu::FW_CPullDownMenu(Environment* ev) :
  76.     fMenuID(-1)
  77. {
  78.     FW_CString32 menuTitle(" ");
  79.     this->PrivInitialize(ev, menuTitle);
  80. }
  81.  
  82. //----------------------------------------------------------------------------------------
  83. //    FW_CPullDownMenu::FW_CPullDownMenu
  84. //----------------------------------------------------------------------------------------
  85.  
  86. FW_CPullDownMenu::FW_CPullDownMenu(Environment* ev, const FW_CString& menuTitle) :
  87.     fMenuID(-1)
  88. {
  89.     this->PrivInitialize(ev, menuTitle);
  90. }
  91.  
  92. //----------------------------------------------------------------------------------------
  93. //    FW_CPullDownMenu::FW_CPullDownMenu
  94. //----------------------------------------------------------------------------------------
  95.  
  96. FW_CPullDownMenu::FW_CPullDownMenu(Environment* ev,
  97.                                    FW_PResourceFile &resFile,
  98.                                    FW_ResourceId resourceId,
  99.                                    unsigned long stringId) :
  100.     fMenuID(-1)
  101. {
  102.     FW_CString32 menuTitle;
  103.     ::FW_LoadStringByID(ev, resFile, resourceId, MULTISTRINGRES, stringId, menuTitle);
  104.     this->PrivInitialize(ev, menuTitle);
  105. }
  106.  
  107. //----------------------------------------------------------------------------------------
  108. //    FW_CPullDownMenu::FW_CPullDownMenu
  109. //----------------------------------------------------------------------------------------
  110.  
  111. FW_CPullDownMenu::FW_CPullDownMenu(Environment* ev, FW_CReadableStream& stream) :
  112.     fMenuID(-1)
  113. {
  114.     FW_CString menuTitle;
  115.     stream >> menuTitle;
  116.  
  117.     this->PrivInitialize(ev, menuTitle);
  118.     
  119.     // ----- Read every items -----
  120.     short count;
  121.     stream >> count;
  122.     
  123.     FW_ASSERT(count>=0 && count <1000);    // just a sanity check
  124.     
  125.     for (short i = 0; i < count; i++)
  126.     {
  127.         FW_CMenuItem* menuItem;
  128.         FW_READ_DYNAMIC_OBJECT(stream, &menuItem, FW_CMenuItem);
  129.         AdoptMenuItemLast(ev, menuItem);
  130.     }
  131. }
  132.  
  133. //----------------------------------------------------------------------------------------
  134. //    FW_CPullDownMenu::PrivInitialize
  135. //----------------------------------------------------------------------------------------
  136.  
  137. void FW_CPullDownMenu::PrivInitialize(Environment* ev, const FW_CString& menuTitle)
  138. {
  139. FW_UNUSED(ev);
  140.     fMenuBar = NULL;
  141.     fParentMenuItem = NULL;
  142.     
  143.     fItems = FW_NEW(FW_TOrderedCollection<FW_CMenuItem>, ());
  144.     
  145. #ifdef FW_BUILD_MAC
  146.     Str255 str;
  147.     menuTitle.ExportPascal(str);
  148.     fPlatformMenu = ::NewMenu(fMenuID, str);
  149. #endif
  150.  
  151. #ifdef FW_BUILD_WIN
  152.     fPlatformMenu.menu = ::CreatePopupMenu();
  153.     menuTitle.ExportCString(fPlatformMenu.strMenu);
  154. #endif
  155. }
  156.  
  157. //----------------------------------------------------------------------------------------
  158. //    FW_CPullDownMenu::~FW_CPullDownMenu
  159. //----------------------------------------------------------------------------------------
  160.  
  161. FW_CPullDownMenu::~FW_CPullDownMenu()
  162. {
  163.     if (fItems)
  164.     {
  165.         FW_CMenuItem* item;
  166.         while ((item = fItems->First()) != NULL)
  167.         {
  168.             fItems->Remove(item);
  169.             delete item;
  170.         }        
  171.         
  172.         delete fItems;
  173.         fItems = NULL;
  174.     }
  175.  
  176. #ifdef FW_BUILD_MAC
  177.     if (fPlatformMenu)
  178.     {
  179.         ::DisposeMenu(fPlatformMenu);
  180.         fPlatformMenu = NULL;
  181.     }
  182. #endif
  183.  
  184. #ifdef FW_BUILD_WIN
  185.     if (fPlatformMenu.menu) 
  186.     {
  187.         ::DestroyMenu(fPlatformMenu.menu);
  188.         fPlatformMenu.menu = NULL;
  189.     }    
  190. #endif
  191. }
  192.  
  193. //----------------------------------------------------------------------------------------
  194. //    FW_CPullDownMenu::AppendTextItem
  195. //----------------------------------------------------------------------------------------
  196.  
  197. void FW_CPullDownMenu::AppendTextItem(Environment* ev,
  198.                                       const FW_CString& text,
  199.                                       ODCommandID commandID,
  200.                                       FW_MenuKey menuKey)
  201. {
  202.     short index = CountItems(ev) + 1;
  203.     FW_CMenuItem* menuItem = FW_NEW(FW_CTextItem, (ev, this, index, text, commandID, menuKey));
  204.     this->AdoptMenuItemLast(ev, menuItem);
  205. }
  206.  
  207. //----------------------------------------------------------------------------------------
  208. //    FW_CPullDownMenu::InsertTextItem
  209. //----------------------------------------------------------------------------------------
  210.  
  211. void FW_CPullDownMenu::InsertTextItem(Environment* ev,
  212.                                       const FW_CString& text,
  213.                                       ODCommandID commandID,
  214.                                       short afterItem,
  215.                                       FW_MenuKey menuKey)
  216. {
  217.     if (afterItem > CountItems(ev))
  218.         afterItem = CountItems(ev);
  219.     
  220.     short index = afterItem + 1;
  221.     
  222.     FW_CMenuItem* menuItem = FW_NEW(FW_CTextItem, (ev, this, index, text, commandID, menuKey));
  223.     this->AdoptMenuItemAfter(ev, menuItem, afterItem);
  224. }
  225.  
  226. //----------------------------------------------------------------------------------------
  227. //    FW_CPullDownMenu::InsertTextItemAfterCommand
  228. //----------------------------------------------------------------------------------------
  229.  
  230. void FW_CPullDownMenu::InsertTextItemAfterCommand(Environment* ev,
  231.                                                   const FW_CString& text,
  232.                                                   ODCommandID commandID,
  233.                                                   ODCommandID afterCommand,
  234.                                                   FW_MenuKey menuKey)
  235. {
  236.     FW_CMenuItem* item = this->PrivGetMenuItem(ev, afterCommand);
  237.     this->InsertTextItem(ev, text, commandID, item->GetIndex(ev), menuKey);
  238. }
  239.  
  240. //----------------------------------------------------------------------------------------
  241. //    FW_CPullDownMenu::AppendToggleItem
  242. //----------------------------------------------------------------------------------------
  243.  
  244. void FW_CPullDownMenu::AppendToggleItem(Environment* ev,
  245.                                         const FW_CString& trueText,
  246.                                         const FW_CString& falseText,
  247.                                         ODCommandID commandID,
  248.                                         FW_MenuKey menuKey)
  249. {
  250.     short index = CountItems(ev) + 1;
  251.     FW_CMenuItem* menuItem = FW_NEW(FW_CToggleItem, (ev, this, index, trueText, falseText, commandID, menuKey));
  252.     this->AdoptMenuItemLast(ev, menuItem);
  253. }
  254.  
  255. //----------------------------------------------------------------------------------------
  256. //    FW_CPullDownMenu::InsertToggleItem
  257. //----------------------------------------------------------------------------------------
  258.  
  259. void FW_CPullDownMenu::InsertToggleItem(Environment* ev,
  260.                                         const FW_CString& trueText,
  261.                                         const FW_CString& falseText,
  262.                                         ODCommandID commandID,
  263.                                         short afterItem,
  264.                                         FW_MenuKey menuKey)
  265. {
  266.     if (afterItem > CountItems(ev))
  267.         afterItem = CountItems(ev);
  268.     
  269.     short index = afterItem + 1;
  270.     
  271.     FW_CMenuItem* menuItem = FW_NEW(FW_CToggleItem, (ev, this, index, trueText, falseText, commandID, menuKey));
  272.     this->AdoptMenuItemAfter(ev, menuItem, afterItem);
  273. }
  274.  
  275. //----------------------------------------------------------------------------------------
  276. //    FW_CPullDownMenu::InsertToggleItemAfterCommand
  277. //----------------------------------------------------------------------------------------
  278.  
  279. void FW_CPullDownMenu::InsertToggleItemAfterCommand(Environment* ev,
  280.                                                     const FW_CString& trueText,
  281.                                                     const FW_CString& falseText,
  282.                                                     ODCommandID commandID,
  283.                                                     ODCommandID afterCommand,
  284.                                                     FW_MenuKey menuKey)
  285. {
  286.     FW_CMenuItem* item = this->PrivGetMenuItem(ev, afterCommand);
  287.     this->InsertToggleItem(ev, trueText, falseText, commandID, item->GetIndex(ev), menuKey);
  288. }
  289.  
  290. //----------------------------------------------------------------------------------------
  291. //    FW_CPullDownMenu::AppendSubMenu
  292. //----------------------------------------------------------------------------------------
  293.  
  294. void FW_CPullDownMenu::AppendSubMenu(Environment* ev,
  295.                                      FW_CPullDownMenu* adoptSubMenu)
  296. {
  297.     short index = CountItems(ev) + 1;
  298.     FW_CMenuItem* menuItem = FW_NEW(FW_CSubMenuItem, (ev, this, index, adoptSubMenu));
  299.     this->AdoptMenuItemLast(ev, menuItem);
  300. }
  301.  
  302. //----------------------------------------------------------------------------------------
  303. //    FW_CPullDownMenu::InsertSubMenu
  304. //----------------------------------------------------------------------------------------
  305.  
  306. void FW_CPullDownMenu::InsertSubMenu(Environment* ev,
  307.                                      FW_CPullDownMenu* adoptSubMenu,
  308.                                      short afterItem)
  309. {
  310.     if (afterItem > CountItems(ev))
  311.         afterItem = CountItems(ev);
  312.     
  313.     short index = afterItem + 1;
  314.     
  315.     FW_CMenuItem* menuItem = FW_NEW(FW_CSubMenuItem, (ev, this, index, adoptSubMenu));
  316.     this->AdoptMenuItemAfter(ev, menuItem, afterItem);
  317. }
  318.  
  319. //----------------------------------------------------------------------------------------
  320. //    FW_CPullDownMenu::InsertSubMenuAfterCommand
  321. //----------------------------------------------------------------------------------------
  322.  
  323. void FW_CPullDownMenu::InsertSubMenuAfterCommand(Environment* ev,
  324.                                                  FW_CPullDownMenu* adoptSubMenu,
  325.                                                  ODCommandID afterCommand)
  326. {
  327.     FW_CMenuItem* item = this->PrivGetMenuItem(ev, afterCommand);
  328.     this->InsertSubMenu(ev, adoptSubMenu, item->GetIndex(ev));
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. //    FW_CPullDownMenu::AppendSeparator
  333. //----------------------------------------------------------------------------------------
  334.  
  335. void FW_CPullDownMenu::AppendSeparator(Environment* ev)
  336. {
  337.     short index = CountItems(ev) + 1;
  338.     FW_CMenuItem* menuItem = FW_NEW(FW_CSeparatorItem, (ev, this, index));
  339.     this->AdoptMenuItemLast(ev, menuItem);
  340. }
  341.  
  342. //----------------------------------------------------------------------------------------
  343. //    FW_CPullDownMenu::InsertSeparator
  344. //----------------------------------------------------------------------------------------
  345.  
  346. void FW_CPullDownMenu::InsertSeparator(Environment* ev,
  347.                                        short afterItem)
  348. {
  349.     if (afterItem > CountItems(ev))
  350.         afterItem = CountItems(ev);
  351.     
  352.     short index = afterItem + 1;
  353.     
  354.     FW_CMenuItem* menuItem = FW_NEW(FW_CSeparatorItem, (ev, this, index));
  355.     this->AdoptMenuItemAfter(ev, menuItem, afterItem);
  356. }
  357.  
  358. //----------------------------------------------------------------------------------------
  359. //    FW_CPullDownMenu::InsertSeparatorAfterCommand
  360. //----------------------------------------------------------------------------------------
  361.  
  362. void FW_CPullDownMenu::InsertSeparatorAfterCommand(Environment* ev,
  363.                                                    ODCommandID afterCommand)
  364. {
  365.     FW_CMenuItem* item = this->PrivGetMenuItem(ev, afterCommand);
  366.     this->InsertSeparator(ev, item->GetIndex(ev));
  367. }
  368.  
  369. //----------------------------------------------------------------------------------------
  370. //    FW_CPullDownMenu::RemoveItem
  371. //
  372. //  If an index greater than the number of items in the menu is specified,
  373. //    the last item is deleted.
  374. //----------------------------------------------------------------------------------------
  375.  
  376. void FW_CPullDownMenu::RemoveItem(Environment* ev, short position)
  377. {
  378.     FW_ASSERT(position > 0);
  379.     
  380.     if (position > CountItems(ev))
  381.         position = CountItems(ev);
  382.     
  383.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);    
  384.     FW_CMenuItem* itemToRemove = NULL;
  385.     
  386.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  387.     {
  388.         short index = item->GetIndex(ev);
  389.         
  390.         if (index == position)
  391.             itemToRemove = item;
  392.         else if (index > position)
  393.         // if the current item is beneath the new item in the menu...
  394.         {
  395.             item->PrivSetIndex(ev, index - 1);
  396.             
  397. #ifdef FW_BUILD_MAC
  398.             if (fMenuBar != NULL)  // need to unregister and re-register the item
  399.             {
  400.                 fMenuBar->PrivMacUnregisterCommand(ev, item->GetCommandID(ev));
  401.                 fMenuBar->PrivMacRegisterCommand(ev, item->GetCommandID(ev), fMenuID, index - 1);
  402.             }
  403. #endif
  404.         }
  405.     }
  406.     
  407.     FW_ASSERT(itemToRemove);
  408.     fItems->Remove(itemToRemove);
  409.     
  410.     if (fMenuBar != NULL)
  411.         itemToRemove->PrivDetach(ev, fMenuBar);
  412.     
  413.     // now, actually delete the item
  414.     
  415. #ifdef FW_BUILD_MAC
  416.     DeleteMenuItem(fPlatformMenu, position);
  417. #endif
  418.  
  419. #ifdef FW_BUILD_WIN
  420.     DeleteMenu(fPlatformMenu.menu, position - 1, MF_BYPOSITION);
  421. #endif
  422.  
  423.     delete itemToRemove;
  424. }
  425.  
  426. //----------------------------------------------------------------------------------------
  427. //    FW_CPullDownMenu::AdoptMenuItemLast
  428. //----------------------------------------------------------------------------------------
  429.  
  430. void FW_CPullDownMenu::AdoptMenuItemLast(Environment* ev, FW_CMenuItem* menuItem)
  431. {
  432.     fItems->AddLast(menuItem);
  433.     
  434.     if (fMenuBar != NULL)
  435.         menuItem->PrivAttach(ev, fMenuBar);
  436. }
  437.  
  438. //----------------------------------------------------------------------------------------
  439. //    FW_CPullDownMenu::AdoptMenuItemAfter
  440. //----------------------------------------------------------------------------------------
  441. //  If afterItem is greater than the number of items in the menu, the item is added to
  442. //  then bottom of the menu; if it's zero, the item is added to the top.
  443.  
  444. void FW_CPullDownMenu::AdoptMenuItemAfter(Environment* ev, FW_CMenuItem* menuItem, short afterItem)
  445. {
  446.     FW_ASSERT(afterItem >= 0 && afterItem <= CountItems(ev));
  447.     
  448.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);    
  449.     FW_CMenuItem* prevItem = NULL;
  450.     
  451.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  452.     {
  453.         short index = item->GetIndex(ev);
  454.         
  455.         if (index == afterItem)
  456.             prevItem = item;
  457.         else if (index > afterItem)
  458.         // if the current item is beneath the new item in the menu...
  459.         {
  460.             item->PrivSetIndex(ev, index + 1);  // adjust item numbers
  461.             
  462. #ifdef FW_BUILD_MAC    
  463.             if (fMenuBar != NULL)  // need to unregister and re-register the item
  464.             {
  465.                 fMenuBar->PrivMacUnregisterCommand(ev, item->GetCommandID(ev));
  466.                 fMenuBar->PrivMacRegisterCommand(ev, item->GetCommandID(ev), fMenuID, index + 1);
  467.             }
  468. #endif
  469.         }
  470.     }
  471.     
  472.     if (afterItem == 0)  // add the item to the menu
  473.         fItems->AddFirst(menuItem);
  474.     else
  475.     {
  476.         FW_ASSERT(prevItem);
  477.         fItems->AddAfter(prevItem, menuItem);
  478.     }
  479.     
  480.     if (fMenuBar != NULL)
  481.         menuItem->PrivAttach(ev, fMenuBar);
  482. }
  483.  
  484. //----------------------------------------------------------------------------------------
  485. //    FW_CPullDownMenu::GetCommandID
  486. //----------------------------------------------------------------------------------------
  487. //    returns FW_kNoCommand if not found or submenu, FW_kSeparatorCommand if separator
  488.  
  489. ODCommandID FW_CPullDownMenu::GetCommandID(Environment* ev, short position) const
  490. {
  491. #ifdef FW_BUILD_MAC
  492.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  493.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  494.     {
  495.         if (item->GetIndex(ev) == position)
  496.             return item->GetCommandID(ev);
  497.     }
  498.         
  499.     return FW_kNoCommand;
  500. #endif
  501.  
  502. #ifdef FW_BUILD_WIN
  503.     return ::GetMenuItemID(fPlatformMenu.menu, position-1);    // zero-based on windows
  504. #endif
  505. }
  506.  
  507. //----------------------------------------------------------------------------------------
  508. //    FW_CPullDownMenu::PrivGetMenuItem
  509. //----------------------------------------------------------------------------------------
  510.  
  511. FW_CMenuItem* FW_CPullDownMenu::PrivGetMenuItem(Environment* ev, ODCommandID commandID) const
  512. {
  513.     FW_ASSERT(commandID != FW_kNoCommand);
  514.     FW_ASSERT(commandID != FW_kSeparatorCommand);
  515.     
  516.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  517.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  518.     {
  519.         if (item->GetCommandID(ev) == commandID)
  520.             return item;
  521.         else 
  522.         {
  523.             FW_CMenuItem* subItem = item->PrivGetMenuItem(ev, commandID);
  524.             if (subItem != NULL)
  525.                 return subItem;
  526.         }
  527.             
  528.     }
  529.         
  530.     return NULL;
  531. }
  532.  
  533. //----------------------------------------------------------------------------------------
  534. //    FW_CPullDownMenu::PrivFindMenuWithID
  535. //----------------------------------------------------------------------------------------
  536.  
  537. FW_CPullDownMenu* FW_CPullDownMenu::PrivFindMenuWithID(Environment* ev, ODMenuID menuID) const
  538. {
  539.     FW_ASSERT(IsAttachedToMenuBar(ev)); // Otherwise it doesn't make sense because menuID 
  540.                                         // are only assigned when the menu is attached
  541.     
  542.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  543.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  544.     {
  545.         FW_CPullDownMenu* subMenu = item->PrivFindMenuWithID(ev, menuID);
  546.         if (subMenu != NULL)
  547.             return subMenu;
  548.     }
  549.     
  550.     return NULL;
  551. }
  552.  
  553. //----------------------------------------------------------------------------------------
  554. //    FW_CPullDownMenu::DisableAll
  555. //----------------------------------------------------------------------------------------
  556.  
  557. void FW_CPullDownMenu::DisableAll(Environment* ev)
  558. {
  559. #ifdef FW_BUILD_MAC
  560.         // ----- On the Mac disable all the items at once
  561.         (*fPlatformMenu)->enableFlags &= 0x00000001;
  562. #endif
  563.  
  564.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  565.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  566.     {
  567.         item->PrivDisableAll(ev);
  568.     }    
  569. }
  570.  
  571. //----------------------------------------------------------------------------------------
  572. //    FW_CPullDownMenu::EnableAll
  573. //----------------------------------------------------------------------------------------
  574.  
  575. void FW_CPullDownMenu::EnableAll(Environment* ev)
  576. {
  577. #ifdef FW_BUILD_MAC
  578.         // ----- On the Mac enale all the items at once
  579.         (*fPlatformMenu)->enableFlags &= 0xFFFFFFFF;
  580. #endif
  581.  
  582.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  583.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  584.     {
  585.         item->PrivEnableAll(ev);
  586.     }    
  587. }
  588.  
  589. //----------------------------------------------------------------------------------------
  590. //    FW_CPullDownMenu::PrivAcquireMenuID
  591. //----------------------------------------------------------------------------------------
  592.  
  593. ODMenuID FW_CPullDownMenu::PrivAcquireMenuID(Environment* ev, FW_CMenuBar* menuBar)
  594. {
  595.     FW_ASSERT(fMenuID == -1);
  596.     fMenuID = menuBar->PrivGetNewMenuID(ev);
  597. #ifdef FW_BUILD_MAC    
  598.     (*fPlatformMenu)->menuID = fMenuID;
  599. #endif
  600.     return fMenuID;
  601. }
  602.  
  603. //----------------------------------------------------------------------------------------
  604. //    FW_CPullDownMenu::PrivRelinquishMenuID
  605. //----------------------------------------------------------------------------------------
  606.  
  607. void FW_CPullDownMenu::PrivRelinquishMenuID(Environment* ev)
  608. {
  609. FW_UNUSED(ev);
  610.     FW_ASSERT(fMenuID != -1);
  611.     fMenuID = -1;
  612. #ifdef FW_BUILD_MAC    
  613.     (*fPlatformMenu)->menuID = -1;
  614. #endif
  615. }
  616.  
  617. //----------------------------------------------------------------------------------------
  618. //    FW_CPullDownMenu::PrivAttach
  619. //----------------------------------------------------------------------------------------
  620.  
  621. void FW_CPullDownMenu::PrivAttach(Environment* ev, FW_CMenuBar* menuBar)
  622. {
  623.     FW_ASSERT(fMenuBar == NULL);
  624.     fMenuBar = menuBar;
  625.     
  626.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  627.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  628.     {
  629.         item->PrivAttach(ev, menuBar);
  630.     }
  631. }
  632.  
  633. //----------------------------------------------------------------------------------------
  634. //    FW_CPullDownMenu::PrivDetach
  635. //----------------------------------------------------------------------------------------
  636.  
  637. void FW_CPullDownMenu::PrivDetach(Environment* ev, FW_CMenuBar* menuBar)
  638. {    
  639.     FW_ASSERT(fMenuBar == menuBar);
  640.     fMenuBar = NULL;
  641.     
  642.     FW_TOrderedCollectionIterator<FW_CMenuItem> ite(fItems);
  643.     for (FW_CMenuItem* item = ite.First(); ite.IsNotComplete(); item = ite.Next())
  644.     {
  645.         item->PrivDetach(ev, menuBar);
  646.     }
  647. }
  648.  
  649. //----------------------------------------------------------------------------------------
  650. //    FW_CPullDownMenu::PrivAttachedToMenuBar
  651. //----------------------------------------------------------------------------------------
  652.  
  653. void FW_CPullDownMenu::PrivAttachedToMenuBar(Environment* ev, ODPart* part, FW_CMenuBar* menuBar, ODMenuID beforeID)
  654. {
  655.     FW_ASSERT(menuBar != NULL);
  656.     FW_ASSERT(fMenuBar == NULL);
  657.     FW_ASSERT(fMenuID == -1);
  658.     
  659.     PrivAcquireMenuID(ev, menuBar);
  660.  
  661.     FW_CAcquiredODMenuBar aqODMenuBar = menuBar->AcquireODMenuBar(ev);
  662.     
  663.     if (beforeID == -1)
  664.     {
  665. #ifdef FW_BUILD_WIN
  666.         // [WIN_PORT]: AddMenuLast takes an ODPlatformMenu* in OD/Win -- different from OD/Mac
  667.         aqODMenuBar->AddMenuLast(ev, fMenuID, &fPlatformMenu, part);
  668. #else
  669.         aqODMenuBar->AddMenuLast(ev, fMenuID, fPlatformMenu, part);
  670. #endif
  671.     }
  672.     else
  673.     {
  674. #ifdef FW_BUILD_WIN
  675.         // [WIN_PORT]: AddMenuBefore takes an ODPlatformMenu* in OD/Win -- different from OD/Mac
  676.         aqODMenuBar->AddMenuBefore(ev, fMenuID, &fPlatformMenu, part, beforeID);
  677. #else
  678.         aqODMenuBar->AddMenuBefore(ev, fMenuID, fPlatformMenu, part, beforeID);
  679. #endif
  680.     }
  681.     
  682.     PrivAttach(ev, menuBar);
  683. }
  684.  
  685. //----------------------------------------------------------------------------------------
  686. //    FW_CPullDownMenu::PrivDetachedFromMenuBar
  687. //----------------------------------------------------------------------------------------
  688.  
  689. void FW_CPullDownMenu::PrivDetachedFromMenuBar(Environment* ev, FW_CMenuBar* menuBar)
  690. {
  691. FW_UNUSED(menuBar);
  692.     FW_ASSERT(fMenuBar != NULL);
  693.     FW_ASSERT(fMenuBar == menuBar);
  694.     
  695.     fMenuBar->PrivRemoveMenu(ev, fMenuID);
  696.     
  697.     PrivDetach(ev, fMenuBar);
  698.     
  699.     PrivRelinquishMenuID(ev);
  700. }
  701.  
  702. //----------------------------------------------------------------------------------------
  703. //    FW_CPullDownMenu::Flatten
  704. //----------------------------------------------------------------------------------------
  705.  
  706. void FW_CPullDownMenu::Flatten(Environment* ev, FW_CWritableStream& stream) const
  707. {
  708.     //----- Save menu data -----
  709.     FW_CString menuTitle;
  710.     short count = CountItems(ev);
  711.  
  712. #ifdef FW_BUILD_MAC
  713.     menuTitle.ReplaceAll((*fPlatformMenu)->menuData);
  714.     FW_ASSERT(count == ::CountMItems(fPlatformMenu));
  715. #endif
  716. #ifdef FW_BUILD_WIN
  717.     menuTitle = fPlatformMenu.strMenu;
  718.     FW_ASSERT(count == ::GetMenuItemCount(fPlatformMenu.menu));
  719. #endif
  720.  
  721.     stream << menuTitle;
  722.     stream << count;
  723.     
  724.     //----- Save menu items -----
  725.     FW_TOrderedCollectionIterator<FW_CMenuItem> itemIter(fItems);
  726.     for (FW_CMenuItem* menuItem = itemIter.First(); itemIter.IsNotComplete(); menuItem = itemIter.Next())
  727.     {
  728.         FW_WRITE_DYNAMIC_OBJECT(stream, menuItem, FW_CMenuItem);
  729.     }
  730. }
  731.